Skip to content

Method: addPlayer(OthelloPlayer, OthelloStrategy)

1: /*
2: * Copyright © 2020-2023 Fachhochschule für die Wirtschaft (FHDW) Hannover
3: *
4: * This file is part of othello-core.
5: *
6: * Othello-core is free software: you can redistribute it and/or modify
7: * it under the terms of the GNU General Public License as published by
8: * the Free Software Foundation, either version 3 of the License, or
9: * (at your option) any later version.
10: *
11: * Othello-core is distributed in the hope that it will be useful,
12: * but WITHOUT ANY WARRANTY; without even the implied warranty of
13: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14: * GNU General Public License for more details.
15: *
16: * You should have received a copy of the GNU General Public License
17: * along with othello-core. If not, see <http://www.gnu.org/licenses/>.
18: */
19: package de.fhdw.gaming.othello.core.domain.impl;
20:
21: import java.util.LinkedHashMap;
22: import java.util.Map;
23: import java.util.Objects;
24: import java.util.Optional;
25:
26: import de.fhdw.gaming.core.domain.DefaultGame;
27: import de.fhdw.gaming.core.domain.DefaultObserverFactoryProvider;
28: import de.fhdw.gaming.core.domain.Game;
29: import de.fhdw.gaming.core.domain.GameBuilder;
30: import de.fhdw.gaming.core.domain.GameException;
31: import de.fhdw.gaming.core.domain.ObserverFactoryProvider;
32: import de.fhdw.gaming.othello.core.domain.OthelloGameBuilder;
33: import de.fhdw.gaming.othello.core.domain.OthelloPlayer;
34: import de.fhdw.gaming.othello.core.domain.OthelloPlayerBuilder;
35: import de.fhdw.gaming.othello.core.domain.OthelloState;
36: import de.fhdw.gaming.othello.core.domain.OthelloStrategy;
37: import de.fhdw.gaming.othello.core.moves.OthelloMove;
38: import de.fhdw.gaming.othello.core.moves.impl.AbstractOthelloMove;
39:
40: /**
41: * Implements {@link OthelloGameBuilder}.
42: */
43: final class OthelloGameBuilderImpl implements OthelloGameBuilder {
44:
45: /**
46: * The {@link ObserverFactoryProvider}.
47: */
48: private ObserverFactoryProvider observerFactoryProvider;
49: /**
50: * The player using black tokens.
51: */
52: private Optional<OthelloPlayer> blackPlayer;
53: /**
54: * The strategy of the player using black tokens.
55: */
56: private Optional<OthelloStrategy> blackPlayerStrategy;
57: /**
58: * The player using white tokens.
59: */
60: private Optional<OthelloPlayer> whitePlayer;
61: /**
62: * The strategy of the player using white tokens.
63: */
64: private Optional<OthelloStrategy> whitePlayerStrategy;
65: /**
66: * The maximum computation time per move in seconds.
67: */
68: private int maxComputationTimePerMove;
69: /**
70: * The number of rows (and columns) of the board.
71: */
72: private int boardSize;
73:
74: /**
75: * Creates an Othello game builder.
76: */
77: OthelloGameBuilderImpl() {
78: this.observerFactoryProvider = new DefaultObserverFactoryProvider();
79: this.blackPlayer = Optional.empty();
80: this.blackPlayerStrategy = Optional.empty();
81: this.whitePlayer = Optional.empty();
82: this.whitePlayerStrategy = Optional.empty();
83: this.maxComputationTimePerMove = GameBuilder.DEFAULT_MAX_COMPUTATION_TIME_PER_MOVE;
84: this.boardSize = OthelloGameBuilder.DEFAULT_BOARD_SIZE;
85: }
86:
87: @Override
88: public OthelloPlayerBuilder createPlayerBuilder() {
89: return new OthelloPlayerBuilderImpl();
90: }
91:
92: @Override
93: public OthelloGameBuilder addPlayer(final OthelloPlayer player, final OthelloStrategy strategy)
94: throws GameException {
95:
96:• if (player.isUsingBlackTokens() && this.blackPlayer.isEmpty()) {
97: this.blackPlayer = Optional.of(Objects.requireNonNull(player, "player"));
98: this.blackPlayerStrategy = Optional.of(Objects.requireNonNull(strategy, "blackPlayerStrategy"));
99:• } else if (!player.isUsingBlackTokens() && this.whitePlayer.isEmpty()) {
100: this.whitePlayer = Optional.of(Objects.requireNonNull(player, "player"));
101: this.whitePlayerStrategy = Optional.of(Objects.requireNonNull(strategy, "whitePlayerStrategy"));
102: } else {
103: throw new GameException(
104: String.format(
105: "Adding player %s is not allowed as a player using the same tokens has already been added.",
106: player));
107: }
108: return this;
109: }
110:
111: @Override
112: public OthelloGameBuilder changeMaximumComputationTimePerMove(final int newMaxComputationTimePerMove) {
113: this.maxComputationTimePerMove = newMaxComputationTimePerMove;
114: return this;
115: }
116:
117: @Override
118: public OthelloGameBuilder changeBoardSize(final int newBoardSize) {
119: this.boardSize = newBoardSize;
120: return this;
121: }
122:
123: @Override
124: public OthelloGameBuilder changeObserverFactoryProvider(final ObserverFactoryProvider newObserverFactoryProvider) {
125: this.observerFactoryProvider = newObserverFactoryProvider;
126: return this;
127: }
128:
129: @Override
130: public Game<OthelloPlayer, OthelloState, OthelloMove, OthelloStrategy> build(final int id)
131: throws GameException, InterruptedException {
132: if (this.blackPlayer.isEmpty() || this.whitePlayer.isEmpty()) {
133: throw new GameException("An Othello game needs two players.");
134: }
135:
136: final OthelloBoardImpl board = new OthelloBoardImpl(this.boardSize);
137: final OthelloState initialState = new OthelloStateImpl(
138: board,
139: this.blackPlayer.get(),
140: this.whitePlayer.get(),
141: true);
142:
143: final Map<String, OthelloStrategy> strategies = new LinkedHashMap<>();
144: strategies.put(initialState.getBlackPlayer().getName(), this.blackPlayerStrategy.orElseThrow());
145: strategies.put(initialState.getWhitePlayer().getName(), this.whitePlayerStrategy.orElseThrow());
146: return new DefaultGame<>(
147: id,
148: initialState,
149: strategies,
150: this.maxComputationTimePerMove,
151: AbstractOthelloMove.class::isInstance,
152: new OthelloRandomMoveGenerator(),
153: this.observerFactoryProvider);
154: }
155: }